package ch.sfug.net.loader {
	import flash.events.ErrorEvent;
	import flash.events.NetStatusEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	import ch.sfug.events.PlayerEvent;
	import ch.sfug.events.StreamBufferEvent;
	import ch.sfug.events.StreamMetaEvent;		

	internal class StreamLoaderStatusHandler {

		private var loader:StreamLoader;
		private var metaInfo:StreamMetaEvent;
		private var seekdelay:Timer;

		public function StreamLoaderStatusHandler( loader:StreamLoader ) {
			this.loader = loader;
			
			// create this hack as at the time of the Seek.NOTIFY event the current time of the stream is not current.
			seekdelay = new Timer(2, 1);
			seekdelay.addEventListener(TimerEvent.TIMER_COMPLETE, dispatchSeek);
		}

		
		public function onMetaData( info:Object ):void {
			metaInfo = new StreamMetaEvent(StreamMetaEvent.META, info);
			loader.dispatchEvent(metaInfo);
		}	

		
		public function handle( evt:NetStatusEvent ):void {
			switch( evt.info.code ) {
				
				case "NetStream.Play.Stop": 

					loader.dispatchEvent(new PlayerEvent(PlayerEvent.END));
					break;
					
				case "NetStream.Play.Start": 
					//TODO: this code blocks preloading of a stream
					//loader.dispatchEvent(new PlayerEvent(PlayerEvent.PLAY));
					break;

				case "NetStream.Buffer.Empty": 
				
					loader.dispatchEvent(new StreamBufferEvent(StreamBufferEvent.BUFFER_EMPTY, loader.bufferLength, loader.bufferTime));
					break;

				case "NetStream.Buffer.Full":
					
					loader.dispatchEvent(new StreamBufferEvent(StreamBufferEvent.BUFFER_FULL, loader.bufferLength, loader.bufferTime));
					break;
					
				case "NetStream.Seek.Notify": 
				
					seekdelay.stop();
					seekdelay.reset();
					seekdelay.start();
					break;


				case "NetConnection.Connect.Closed": 
				case "NetConnection.Connect.Failed ": 
				case "NetStream.Play.Failed": 
				case "NetStream.Play.StreamNotFound": 
					
					loader.stopDownloadProgress();
					loader.dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, evt.info.code + ": " + loader.request.url));				
					break;
			}
		}

		
		private function dispatchSeek(event:TimerEvent):void {
			loader.dispatchEvent( new PlayerEvent( PlayerEvent.SEEK ) );
		}

		
		public function get duration():Number {
			return ( metaInfo != null) ? metaInfo.duration : 0;
		}

		
		public function get size():Rectangle {
			return ( metaInfo != null) ? metaInfo.size : null;
		}
	}
}